#ifndef PAVAR_H
#define PAVAR_H

#include <QObject>
#include <QJsonObject>
#include <QJsonValue>
#include <QVariant>
#include <QJsonArray>

typedef QPair<QVariant,QVariant> VariantPair;
typedef QList<VariantPair> VariantPairList;
class PaKey{
public:
    PaKey(){}
    PaKey& operator<<(const QVariant &key){_keys<<key;return *this;}
protected:
    QVariantList _keys;
};

class PaVarRef;
class PaVar{
    friend class PaVarRef;
public:
    PaVar() {}
    PaVar(const QVariant &var):_root(var){}
    QVariant get(const QVariantList &keys={}) const;
    void set(const QVariantList &keys, const QVariant &value);
    void del(const QVariantList &keys);
    bool exists(const QVariantList &keys) const;
    int count(const QVariantList &keys) const;

    // list
    void append(const QVariantList &keys, const QVariant &value);
    void insert(const QVariantList &keys, int index, const QVariant &value);
    QVariant at(const QVariantList &keys, int index) const;
    QVariant first(const QVariantList &keys) const;
    QVariant last(const QVariantList &keys) const;
    int indexAt(const QVariantList &keys, const QVariant &value) const;
    void removeAt(const QVariantList &keys, int index);
    QVariant takeFirst(const QVariantList &keys);
    QVariant takeLast(const QVariantList &keys);

private:
    void addNode(QList<VariantPair> &varList, const QVariant &key);
    void addNode(const QVariant &parentVar, QList<VariantPair> &varList, const QVariant &key);
    bool saveNode(QVariant &parent, const QVariant &key, const QVariant &value);
    bool saveListNode(QVariant &parent, int index, const QVariant &value);
    bool saveMapNode(QVariant &parent, const QString &string, const QVariant &value);

    QString keyString(const QVariantList &keys);

private:
    QVariant _root;
};

class PaVarRef : public PaKey{
public:
    PaVarRef(PaVar &paVar);
    PaVarRef(const PaVarRef &paVarRef);
    PaVarRef operator[](const QVariant &key) const;
    void operator=(const PaVarRef &paVarRef);
    void operator=(const QVariant &value);

    QVariant toValue() const;
    QVariantList toList() const;
    QVariantMap toMap() const;
    int toInt() const;
    QString toString() const;
    QString toJsonString(bool indented = true) const;
    void fromJsonString(const QString &jsonString);

    void del();
    bool exists() const;
    int count() const;

    // list
    void append(const QVariant &value);
    void insert(int index, const QVariant &value);
    QVariant at(int index) const;
    QVariant first() const;
    QVariant last() const;
    int indexAt(const QVariant &value) const;
    void removeAt(int index);
    QVariant takeFirst();
    QVariant takeLast();

private:
    QVariant value() const;
    void setValue(const QVariant &value);

private:
    PaVar &_paVar;
};

#endif
